package com.glink.manage.service.barriergate;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.date.DateUtil;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.util.BaseCommonUtils;
import com.glink.manage.common.Constants;
import com.glink.manage.common.enums.MqttEnum;
import com.glink.manage.dto.barriergate.lianyi.CarBarrierGateListAddDTO;
import com.glink.manage.dto.barriergate.lianyi.CarBarrierGateListAddDataDTO;
import com.glink.manage.dto.mqtt.CarBarrierGateListDeleteDTO;
import com.glink.manage.dto.mqtt.CarBarrierGateListDeleteDataDTO;
import com.glink.manage.dto.mqtt.CarBarrierGateListQueryDTO;
import com.glink.manage.dto.vehicle.VehicleSyncDTO;
import com.glink.manage.mqtt.MqttService;
import com.glink.manage.mqtt.service.MessageResultService;
import com.glink.manage.service.PersonSyncRecordService;
import com.glink.manage.vo.barriergate.PersonSyncDataPathParamsVO;
import com.glink.manage.vo.barriergate.PersonSyncDataVO;
import com.glink.manage.vo.mqtt.PersonDeleteDataVO;
import com.glink.manage.vo.mqtt.PersonDeleteVO;
import com.glink.manage.vo.mqtt.PersonSyncVO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Created by IntelliJ IDEA.
 * 联义道闸
 * @Author : qiushaoshan
 * @create 2025/2/18 16:25
 */
@Service
@Slf4j
public class BarrierGate_LianYi {
    
    // 请求地址前缀
    @Value("${barrier_gate.callback.prefix.url:http://192.168.1.31}")
    private String callbackPrefixUrl;

    // 数据执行反馈结果
    @Value("${barrier_gate.person.notify:/device/notify}")
    private String personNotify;

    // 人员同步接口
    @Value("${barrier_gate.person.sync_person:/device/sync_person}")
    private String personSyncPerson;

    // 车辆开始准入初始化
    private static final String CYCLE_START_INIT = "2020/01/01 00:00:00";
    // 车辆结束准入初始化
    private static final String CYCLE_END_INIT = "2100/01/01 00:00:00";

    public final TimedCache<String, List<String>> listAddCache = CacheUtil.newTimedCache(120000L);

    @Autowired
    @Lazy
    private MessageResultService messageResultService;
    
    @Autowired
    private MqttService mqttService;

    @Autowired
    @Lazy
    private PersonSyncRecordService personSyncRecordService;

    /**
     * 根据设备号下发数据
     * @param sn 设备号
     * @param syncDTOList 同步车辆数据
     */
    public void issuedCarBySn(String sn, List<VehicleSyncDTO> syncDTOList){
        List<CarBarrierGateListAddDataDTO> addDataDTOList = Lists.newArrayList();

        if(CollectionUtils.isNotEmpty(syncDTOList)){

            syncDTOList.forEach(syncDTO -> {
                if(StringUtils.isNotBlank(syncDTO.getIfDepartment())){

                    String licensePlate = syncDTO.getLicensePlate();

                    if(StringUtils.equals(syncDTO.getIfDepartment(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)){
                        CarBarrierGateListAddDataDTO addDataDTO = new CarBarrierGateListAddDataDTO();
                        addDataDTO.setPlatenum(licensePlate);
                        addDataDTO.setType(StringUtils.equals(syncDTO.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01) ? MqttEnum.Blacklist.B.getKey() : MqttEnum.Blacklist.W.getKey());

                        String startTimeStr = Objects.nonNull(syncDTO.getCycleStart()) ? Constants.DATE_FORMAT_DAY.format(syncDTO.getCycleStart()) : "";
                        String endTimeStr = Objects.nonNull(syncDTO.getCycleEnd()) ? Constants.DATE_FORMAT_DAY.format(syncDTO.getCycleEnd()) : "";
                        addDataDTO.setStart(startTimeStr);
                        addDataDTO.setEnd(endTimeStr);
                        addDataDTOList.add(addDataDTO);
                    }else if(StringUtils.equals(syncDTO.getIfDepartment(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)){
                        CarBarrierGateListAddDataDTO addDataDTO = new CarBarrierGateListAddDataDTO();
                        addDataDTO.setPlatenum(licensePlate);
                        addDataDTO.setType(StringUtils.equals(syncDTO.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01) ? MqttEnum.Blacklist.B.getKey() : MqttEnum.Blacklist.W.getKey());

                        addDataDTO.setStart(CYCLE_START_INIT);
                        addDataDTO.setEnd(CYCLE_END_INIT);
                        addDataDTOList.add(addDataDTO);
                    }
                }
            });

            if(CollectionUtils.isNotEmpty(addDataDTOList)){
                log.info("车辆道闸：sn:{}, 下发名单数量：{}", sn, addDataDTOList.size());
                listAdd(sn, addDataDTOList);
            }
        }
    }


    /**
     * 添加记录
     * @param listAddDataDTOList 记录信息
     */
    public void listAdd(String sn, List<CarBarrierGateListAddDataDTO> listAddDataDTOList){
        if(CollectionUtils.isNotEmpty(listAddDataDTOList)){
            CarBarrierGateListAddDTO listAddDTO = new CarBarrierGateListAddDTO();
            listAddDTO.setCmd(MqttEnum.CarBarrierGateCmd.LIST_ADD.getKey());
            listAddDTO.setMsg_id(getMsgId());
            listAddDTO.setList_data(listAddDataDTOList);
            messageResultService.sendMessage_lianYi(sn, listAddDTO);

            List<String> platenumList = listAddDataDTOList.stream().map(CarBarrierGateListAddDataDTO::getPlatenum).collect(Collectors.toList());
            listAddCache.put(listAddDTO.getMsg_id(), platenumList);
        }
    }


    /**
     * 名单删除
     * @param sn 设备SN码
     * @param listDeleteDataDTOList 删除的名单
     */
    public void listDelete(String sn, List<CarBarrierGateListDeleteDataDTO> listDeleteDataDTOList){
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(listDeleteDataDTOList)){
            CarBarrierGateListDeleteDTO listDeleteDTO = new CarBarrierGateListDeleteDTO();
            listDeleteDTO.setCmd(MqttEnum.CarBarrierGateCmd.LIST_DELETE.getKey());
            listDeleteDTO.setMsg_id(getMsgId());
            listDeleteDTO.setList_data(listDeleteDataDTOList);
            messageResultService.sendMessage_lianYi(sn, listDeleteDTO);
        }
    }


    /**
     * 名单查询
     *
     * @param sn           设备SN码
     * @param licensePlate 车牌
     */
    public void listQuery(String sn, String licensePlate) {
        CarBarrierGateListQueryDTO queryDTO = new CarBarrierGateListQueryDTO();
        queryDTO.setCmd(MqttEnum.CarBarrierGateCmd.LIST_QUERY.getKey());
        queryDTO.setMsg_id(getMsgId());
        queryDTO.setPlatenum(licensePlate);
        messageResultService.sendMessage_lianYi(sn, queryDTO);
    }

    public void listDeleteAll(){
        CarBarrierGateListDeleteDTO listDeleteDTO = new CarBarrierGateListDeleteDTO();
        listDeleteDTO.setCmd(MqttEnum.CarBarrierGateCmd.LIST_DELETE_ALL.getKey());
        listDeleteDTO.setMsg_id(getMsgId());
        messageResultService.sendMessage_lianYi("", listDeleteDTO);
    }
    
    private String getMsgId() {
        return DateUtil.date().getTime() + BaseCommonUtils.generateUUID().substring(0, 7);
    }

    /**
     * 根据设备号下发数据
     * @param sn 设备号
     * @param syncDTO 同步车辆数据
     */
    public void issuedCarBySn(String sn, VehicleSyncDTO syncDTO){
        CarBarrierGateListAddDataDTO addDataDTOList = null;

        if(Objects.nonNull(syncDTO)){
            if(StringUtils.isNotBlank(syncDTO.getIfDepartment())){

                String licensePlate = syncDTO.getLicensePlate();

                if(StringUtils.equals(syncDTO.getIfDepartment(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)){
                    addDataDTOList = new CarBarrierGateListAddDataDTO();
                    addDataDTOList.setPlatenum(licensePlate);
                    addDataDTOList.setType(StringUtils.equals(syncDTO.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01) ? MqttEnum.Blacklist.B.getKey() : MqttEnum.Blacklist.W.getKey());

                    String startTimeStr = Objects.nonNull(syncDTO.getCycleStart()) ? Constants.DATE_FORMAT_DAY.format(syncDTO.getCycleStart()) : "";
                    String endTimeStr = Objects.nonNull(syncDTO.getCycleEnd()) ? Constants.DATE_FORMAT_DAY.format(syncDTO.getCycleEnd()) : "";
                    addDataDTOList.setStart(startTimeStr);
                    addDataDTOList.setEnd(endTimeStr);
                }else if(StringUtils.equals(syncDTO.getIfDepartment(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)){
                    addDataDTOList = new CarBarrierGateListAddDataDTO();
                    addDataDTOList.setPlatenum(licensePlate);
                    addDataDTOList.setType(StringUtils.equals(syncDTO.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01) ? MqttEnum.Blacklist.B.getKey() : MqttEnum.Blacklist.W.getKey());

                    addDataDTOList.setStart(CYCLE_START_INIT);
                    addDataDTOList.setEnd(CYCLE_END_INIT);
                }
            }

            if(Objects.nonNull(addDataDTOList)){
                log.info("车辆道闸：sn:{}, 下发名单：{}", sn, addDataDTOList);
                listAdd(sn, Collections.singletonList(addDataDTOList));
            }
        }
    }

    /**
     * 下发删除设备
     * @param sn 设备号
     * @param licensePlate 车牌号
     */
    public void issuedListDeleteByLicensePlate(String sn, String licensePlate){
        try {
            CarBarrierGateListDeleteDataDTO deleteDataDTO = new CarBarrierGateListDeleteDataDTO();
            deleteDataDTO.setPlatenum(licensePlate);
            listDelete(sn, Collections.singletonList(deleteDataDTO));
        }catch (Exception e){
            log.error("车辆下发失败，sn:{}, sn:{}", sn, licensePlate, e);
        }
    }

    /**
     * 组装mqtt数据-人员下发
     * @param devSno 设备号
     * @param personIdList 人员列表
     * @param notSyncNum 待同步数量
     */
    public void issuedPersonData_syncPerson(String devSno, List<Integer> personIdList, Integer notSyncNum){
       
        Integer syncNum = personSyncRecordService.countByDevSno(devSno);
        syncNum = syncNum == null ? 0 : syncNum;
        notSyncNum = notSyncNum == null ? 0 : notSyncNum;
        
        PersonSyncVO personSyncVO = new PersonSyncVO();
        personSyncVO.setMethod(MqttEnum.PersonBarrierGate.SYNC_PERSON.getKey());
        personSyncVO.setNotify(callbackPrefixUrl + personNotify);

        // 人员数据
        PersonSyncDataVO personSyncDataVO = new PersonSyncDataVO();
        personSyncDataVO.setPath(callbackPrefixUrl + personSyncPerson);

        // 获取人员信息接口需要携带的参数
        PersonSyncDataPathParamsVO pathParamsVO = new PersonSyncDataPathParamsVO();
        pathParamsVO.setDev_sno(devSno);
        pathParamsVO.setPerson_list(personIdList);
        pathParamsVO.setPerson_type(MqttEnum.PersonType.WHITE_LIST.getKey());
        pathParamsVO.setTotal(notSyncNum + syncNum);
        pathParamsVO.setOffset(notSyncNum);

        personSyncDataVO.setPath_params(pathParamsVO);

        personSyncVO.setData(personSyncDataVO);

        mqttService.sendMessage(devSno, personSyncVO);
    }

    /**
     * 删除人员
     * @param devSnoList 设备号
     * @param personId 人员ID
     */
    public void issuedPersonData_deletePerson(List<String> devSnoList, Integer personId){
        if(CollectionUtils.isNotEmpty(devSnoList)){
            PersonDeleteVO personDeleteVO = new PersonDeleteVO();
            personDeleteVO.setMethod(MqttEnum.PersonBarrierGate.DELETE_PERSON.getKey());
            personDeleteVO.setNotify(callbackPrefixUrl + personNotify);

            // 人员数据
            PersonDeleteDataVO personDeleteDataVO = new PersonDeleteDataVO();
            personDeleteDataVO.setPerson_list(Collections.singletonList(personId));
            personDeleteDataVO.setPerson_type("4");

            personDeleteVO.setData(personDeleteDataVO);

            devSnoList.forEach(devSno -> {
                mqttService.sendMessage(devSno, personDeleteVO);

                personSyncRecordService.removeByDevSnoAndId(devSno, personId);
            });
        }
    }
}
